package com.dbflow5.transaction;

import com.dbflow5.BaseUnitTest;
import com.dbflow5.TestDatabase;
import com.dbflow5.config.FlowManager;
import com.dbflow5.models.SimpleModel_Table;
import com.dbflow5.models.SimpleTestModels;
import com.dbflow5.models.TwoColumnModel_Table;
import com.dbflow5.query.SQLite;
import com.dbflow5.structure.Model;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;
import java.util.function.Function;

public class CoroutinesTest extends BaseUnitTest {
    @Test
    public void testTransact() {
        TaskDispatcher globalTaskDispatcher = getContext().getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.syncDispatch(() -> FlowManager.database(TestDatabase.class, db -> {
            for (int i = 0; i < 9; i++) {
                SimpleTestModels.SimpleModel simpleModel = new SimpleTestModels.SimpleModel(""+i);
                Model.save(SimpleTestModels.SimpleModel.class, simpleModel, db);
            }
            List<SimpleTestModels.SimpleModel> query = SQLite.select().from(SimpleTestModels.SimpleModel.class).where(SimpleModel_Table.name.eq("5")).queryList(db);
            Assert.assertEquals(1, query.size());

            long result = SQLite.delete(SimpleTestModels.SimpleModel.class).where(SimpleModel_Table.name.eq("5")).executeUpdateDelete(db);
            Assert.assertEquals(1L, result);
            return null;
        }));
    }

    @Test
    public void testAwaitSaveAndDelete() {
        TaskDispatcher globalTaskDispatcher = getContext().getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.syncDispatch(() -> FlowManager.database(TestDatabase.class, db -> {
            SimpleTestModels.SimpleModel simpleModel = new SimpleTestModels.SimpleModel("Name");
            boolean result = Model.save(SimpleTestModels.SimpleModel.class, simpleModel, db);
            assert result;

            assert Model.delete(SimpleTestModels.SimpleModel.class, simpleModel, db);
            return null;
        }));
    }

    @Test
    public void testAwaitInsertAndDelete() {
        TaskDispatcher globalTaskDispatcher = getContext().getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.syncDispatch(new Runnable() {
            @Override
            public void run() {
                FlowManager.database(TestDatabase.class, new Function<TestDatabase, Void>() {
                    @Override
                    public Void apply(TestDatabase db) {
                        SimpleTestModels.SimpleModel simpleModel = new SimpleTestModels.SimpleModel("Name");
                        long result = Model.insert(SimpleTestModels.SimpleModel.class, simpleModel, db);
                        assert result > 0;
                        assert Model.delete(SimpleTestModels.SimpleModel.class, simpleModel, db);
                        return null;
                    }
                });
            }
        });
    }

    @Test
    public void testAwaitUpdate() {
        TaskDispatcher globalTaskDispatcher = getContext().getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.syncDispatch(() -> FlowManager.database(TestDatabase.class, db -> {
            SimpleTestModels.TwoColumnModel simpleModel = new SimpleTestModels.TwoColumnModel("Name", 5);
            boolean result = Model.save(SimpleTestModels.TwoColumnModel.class, simpleModel, db);
            assert result;

            simpleModel.id = 5;
            boolean update = Model.update(SimpleTestModels.TwoColumnModel.class, simpleModel, db);
            assert update;

            SimpleTestModels.TwoColumnModel loadedModel = SQLite.select().from(SimpleTestModels.TwoColumnModel.class).where(TwoColumnModel_Table.id.eq(5)).querySingle(db);
            Assert.assertEquals(loadedModel.id, 5);
            return null;
        }));
    }
}
